package model;

import java.util.ArrayList;

public class LockInfo {
	//Status
	public static final int GRANTED = 1;
	public static final int WAITING = 2;
	
	//Lock Type
	public static final int RL = 0;
	public static final int UL = 1;
	public static final int WL = 2;
	public static final int IRL = 3;
	public static final int IUL = 4;
	public static final int IWL = 5;
	
	private int trId;
	private int trIdNext;
	private String objId;
	private int lockType;
	private int status;
	
	private boolean verified;

/**
 * 
 * @param trId
 * @param trIdNet
 * @param objId
 * @param lockType
 * @param status
 */
	public LockInfo(int trId, int trIdNet, String objId, int lockType, int status){
		this.trId = trId;
		this.objId = objId;
		this.lockType = lockType;
		this.status = status;
		this.trIdNext = trIdNet;
	}

	public int getTrId() {
		return trId;
	}

	public void setTrId(int trId) {
		this.trId = trId;
	}

	public String getObjId() {
		return objId;
	}

	public void setObjId(String objId) {
		this.objId = objId;
	}

	public int getLockType() {
		return lockType;
	}

	public void setLockType(int lockType) {
		this.lockType = lockType;
	}

	public int getStatus() {
		return status;
	}

	public void setStatus(int status) {
		this.status = status;
	}

	public int getTrIdNext() {
		return trIdNext;
	}

	public void setTrIdNext(int trIdNext) {
		this.trIdNext = trIdNext;
	}
	
	public boolean isVerified() {
		return verified;
	}

	public void setVerified(boolean verified) {
		this.verified = verified;
	}
	
	/**
	 * 
	 * @param trId
	 * @param tridNext
	 * @param lockInfo
	 * @return
	 */
	private static boolean isThereDeadLock(int trId, int tridNext, ArrayList<LockInfo> lockInfo){
		if(trId == tridNext){
			return true;
		}else{
			int findNext = nextTrLock(tridNext, lockInfo);
			if(findNext > -1){
				return isThereDeadLock(trId, lockInfo.get(findNext).getTrIdNext(), lockInfo);
			}else{
				return false;
			}
		}
	}

	private static int nextTrLock(int tridNext, ArrayList<LockInfo> lockInfo) {
		int ret = -1;
		for (int i = 0; i < lockInfo.size(); i++) {
			LockInfo temp = lockInfo.get(i);
			if(temp.getTrId() == tridNext && temp.getTrIdNext() > 0 && !temp.isVerified() && temp.getStatus() == LockInfo.GRANTED){
				ret = i;
				temp.setVerified(true);
				break;
			}
		}
		return ret;
	}

	public static void notVerified(ArrayList<LockInfo> lista) {
		for (LockInfo lockInfo : lista) {
			lockInfo.setVerified(false);
		}
		
	}

	public static boolean deadLockCheck(ArrayList<LockInfo> lista) {
		boolean b = false;
		for (LockInfo li : lista) {
			b = LockInfo.isThereDeadLock(li.getTrId(), li.getTrIdNext(), lista);
			LockInfo.notVerified(lista);
			if(b){
				break;
			}
		}
		return b;
	}

}